package com.qdlc.p2p.biz.service.impl;

import java.io.File;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.executer.AbstractExecuter;
import com.qdlc.p2p.biz.executer.ExecuterHelper;
import com.qdlc.p2p.biz.executer.impl.ApplyVipExecuter;
import com.qdlc.p2p.biz.executer.impl.UserRegisterExecuter;
import com.qdlc.p2p.biz.service.UserCacheService;
import com.qdlc.p2p.biz.service.user.identify.UserIdentifyFactory;
import com.qdlc.p2p.biz.service.user.identify.UserIdentifyWay;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.util.mail.Mail;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.TppChinapnrException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.common.util.ValidateUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dao.ScoreDao;
import com.qdlc.p2p.dal.dao.UserCacheDao;
import com.qdlc.p2p.dal.dao.UserCreditDao;
import com.qdlc.p2p.dal.dao.UserDao;
import com.qdlc.p2p.dal.dao.UserIdentifyDao;
import com.qdlc.p2p.dal.dao.UserUploadDao;
import com.qdlc.p2p.dal.dao.UserVipApplyDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.Score;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserCache;
import com.qdlc.p2p.dal.dto.UserCredit;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.dto.UserUpload;
import com.qdlc.p2p.dal.dto.UserVipApply;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.model.UserCacheModel;
import com.qdlc.p2p.dal.model.UserModel;
import com.qdlc.p2p.dal.util.UserUtils;

@Service("userCacheService")
public class UserCacheServiceImpl implements UserCacheService {

    private Logger logger = Logger.getLogger(UserCacheServiceImpl.class);

    @Resource
    private UserCacheDao userCacheDao;

    @Resource
    private AccountDao accountDao;

    @Resource
    private UserIdentifyDao userIdentifyDao;

    @Resource
    private UserVipApplyDao userVipApplyDao;

    @Resource
    private UserDao userDao;

    @Resource
    private UserCreditDao userCreditDao;

    @Resource
    private ScoreDao scoreDao;

    @Resource
    private UserUploadDao userUploadDao;

    @Override
    public UserCacheModel getUserCache(long userId) {
        return userCacheDao.getUserCache(userId);
    }

    @Override
    public UserCache findByUserId(long userId) {
        return userCacheDao.findByUserId(userId);
    }

    @Override
    public Object doRealname(User user, UserModel model) throws Exception {
        model = makeModel(model, user);
        UserIdentifyFactory attestationFactory = new UserIdentifyFactory(user.getUserId(), model);
        UserIdentifyWay attestationWay = attestationFactory.realname();
        return attestationWay.doRealname();
    }

    private static UserModel makeModel(UserModel model, User user) {
        model.setUserName(user.getUserName());
        model.setEmail(user.getEmail());
        model.setUserId(user.getUserId());
        return model;
    }

    @Override
    public void updateAvaPic(User u, String path) {
        User user = userDao.find(u.getUserId());
        UserCache userCache = UserUtils.getUserCacheByUserId(user.getUserId());
        userCache.setAvatarPicPath(path);
        userCacheDao.update(userCache);
    }

    @Override
    public void modify(long userId, String card_id) {
        userCacheDao.modify(userId, card_id);
    }

    @Override
    public void modify(long userId, String card_id, String card_positive,
                       String card_opposite) {
        userCacheDao.modify(userId, card_id, card_positive, card_opposite);
    }

    @Override
    public void modify(long userId, UserModel model, String cardPositive,
                       String cardOpposite) {
        String cardId = model.getCardId();
        if (!StringUtil.isCard(model.getCardId())) {
            throw new UserException("身份证格式不对，请检查！", 1);
        }
        int length = cardId.length();
        char sexNum;
        if (length == 15) {
            sexNum = cardId.charAt(length - 1);
        } else {
            sexNum = cardId.charAt(length - 2);
        }
        // 获取性别 1:男,0:女
        int sex = sexNum % 2;

        User user = userDao.find(userId);
        user.setRealName(model.getRealName());
        user.setCardId(cardId);
        UserCache userCache = UserUtils.getUserCacheByUserId(user.getUserId());
        userCache.setCardOpposite(cardOpposite);
        userCache.setCardPositive(cardPositive);
        userCache.setSex(sex);
        userCacheDao.update(userCache);
    }

    /**
     * 申请vip业务处理
     */
    @Override
    public UserIdentify applyVip(User user) {
        logger.debug("vip条件判断");

        double vipFee = SystemConfigHelper.getDoubleValue(Nid.VIP_FEE);
        Account account = accountDao.findByUserId(user.getUserId());

        UserIdentify userIdentify = userIdentifyDao.findByUserId(user.getUserId());
        if (userIdentify.getVipStatus() == 1) {
            throw new BusinessException("您已经是vip用户，请您查看", 1);
        }
        if (userIdentify.getVipStatus() == 2) {
            throw new BusinessException("您申请的vip审核，正在审核中，请您查看", 1);
        }
        if (account.getUseMoney() < vipFee) {
            throw new BusinessException("余额不足，请您充值", 1);
        }

        logger.debug("用户资金、操作日志、通知处理");
        AbstractExecuter executer = ExecuterHelper.getExecuter(ApplyVipExecuter.class);
        executer.execute(vipFee, user);

        logger.debug("进入vip申请业务处理...");
        UserVipApply userVipApply = new UserVipApply();
        userVipApply.setAddIp(Global.getIP());
        userVipApply.setRemark(Global.getTransfer().get("vipRemark") + "");// 备注
        userVipApply.setAddTime(DateUtil.getNow());
        userVipApply.setMoney(vipFee);
        userVipApply.setStatus((byte) 0);
        userVipApply.setUser(user);
        userVipApplyDao.save(userVipApply);

        userIdentify.setVipStatus(2);// 待审核状态
        userIdentifyDao.update(userIdentify);
        return userIdentify;
    }

    @Override
    public void update(UserCache userCache) {
        userCacheDao.update(userCache);
    }

    @Override
    public void update(UserCache userCache, List<UserUpload> list, long[] delIds) {
        userUploadDao.save(list);
        userCacheDao.merge(userCache);
        if (delIds != null) {
            for (long id : delIds) {
                UserUpload uu = userUploadDao.find(id);
                userUploadDao.delete(id);
                String realPath = ServletActionContext.getServletContext().getRealPath(uu.getPicPath());
                new File(realPath).delete();
            }
        }
    }

    @Override
    public void updateStatus() {
        userCacheDao.updateStatus();
    }

    @Override
    public void save(UserCache model, List<UserUpload> list) {
        User user = UserUtils.getUserById(model.getUserId());
        checkInfo(model);
        user.setRealName(user.getRealName().trim());
        user.setUserName(user.getRealName());
        user.setAddTime(DateUtil.getNow());
        // 用户附属信息
        userCacheDao.save(model);
        // 后台开户实物照信息
        for (UserUpload uu : list) {
            uu.setUser(user);
            userUploadDao.save(uu);
        }
        // 用户认证信息
        userIdentifyDao.save(new UserIdentify(user.getUserId()));
        // 资金账户
        accountDao.save(new Account(user.getUserId()));
        // 用户amount
        userCreditDao.save(new UserCredit(user));
        // 添加用户积分信息
        scoreDao.save(new Score(user));
        // 发送激活邮件
        Global.setTransfer("activeUrl", "/user/doRegisterStep1.html?id=" + Mail.getInstance().getdecodeIdStr(user));
        Global.setTransfer("user", user);
        AbstractExecuter executer = ExecuterHelper.getExecuter(UserRegisterExecuter.class);
        executer.execute(0, user);
    }

    /**
     * 校验后台开户
     *
     * @param model
     */
    private void checkInfo(UserCache model) {
        User user = UserUtils.getUserById(model.getUserId());
        int count = userDao.countByMobilePhone(user.getMobilePhone());
        if (count > 0) {
            throw new UserException("该手机号码已被使用！", 1);
        }
        if (!StringUtil.isPhone(user.getMobilePhone())) {
            throw new UserException("手机号码格式不正确！", 1);
        }
        if (!ValidateUtil.isEmail(user.getEmail())) {
            throw new UserException("借款人（负责人）邮箱格式错误！", 1);
        }
        int hasEmail = userDao.countByEmail(user.getEmail());
        if (hasEmail > 0) {
            throw new UserException("借款人邮箱已经被使用！", 1);
        }
        if (!"".equals(model.getCompanyEmail())) {
            if (!ValidateUtil.isEmail(model.getCompanyEmail())) {
                throw new UserException("公司邮箱格式错误！", 1);
            }
            int hasCompanyEmail = userDao.countByEmail(model.getCompanyEmail());
            if (hasCompanyEmail > 0) {
                throw new UserException("公司邮箱已经被使用！", 1);
            }
        }
        if (!StringUtil.isCard(user.getCardId())) {
            throw new UserException("身份证格式不对，请检查！", 1);
        }
    }

    @Override
    public PageDataList<UserCacheModel> userList(int pageNumber, int pageSize, UserCache model) {
        return userCacheDao.userList(pageNumber, pageSize, model);
    }

    @Override
    public UserCache findById(long id) {
        return userCacheDao.find(id);
    }

    @Override
    public Object tppRealName(UserModel model, User user) {
        UserIdentify iden = userIdentifyDao.findByUserId(user.getUserId());
        //校验用户手机邮箱
        if (iden.getMobilePhoneStatus() != 1) {
            throw new TppChinapnrException(MessageUtil.getMessage("MF104001004"));
        }
        TppModel tppModel = new TppModel();
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        tppModel.setUser(user);
        String name = model.getRealName();
        String cardId = model.getCardId();
        user.setCardId(cardId);
        user.setRealName(name);
        tppModel.setUser(user);
        return tppService.tppRegister(tppModel);
    }
}
